﻿using System;
using GeoAPI.Geometries;

namespace NetTopologySuite.Geometries.Utilities
{
	public class AffineTransformationBuilder
	{
		public AffineTransformationBuilder(Coordinate src0, Coordinate src1, Coordinate src2, Coordinate dest0, Coordinate dest1, Coordinate dest2)
		{
			this._src0 = src0;
			this._src1 = src1;
			this._src2 = src2;
			this._dest0 = dest0;
			this._dest1 = dest1;
			this._dest2 = dest2;
		}

		public AffineTransformation GetTransformation()
		{
			if (this.Compute())
			{
				return new AffineTransformation(this._m00, this._m01, this._m02, this._m10, this._m11, this._m12);
			}
			return null;
		}

		private bool Compute()
		{
			double[] b = new double[]
			{
				this._dest0.X,
				this._dest1.X,
				this._dest2.X
			};
			double[] array = this.Solve(b);
			if (array == null)
			{
				return false;
			}
			this._m00 = array[0];
			this._m01 = array[1];
			this._m02 = array[2];
			double[] b2 = new double[]
			{
				this._dest0.Y,
				this._dest1.Y,
				this._dest2.Y
			};
			double[] array2 = this.Solve(b2);
			if (array2 == null)
			{
				return false;
			}
			this._m10 = array2[0];
			this._m11 = array2[1];
			this._m12 = array2[2];
			return true;
		}

		private double[] Solve(double[] b)
		{
			return Matrix.Solve(new double[][]
			{
				new double[]
				{
					this._src0.X,
					this._src0.Y,
					1.0
				},
				new double[]
				{
					this._src1.X,
					this._src1.Y,
					1.0
				},
				new double[]
				{
					this._src2.X,
					this._src2.Y,
					1.0
				}
			}, b);
		}

		private readonly Coordinate _src0;

		private readonly Coordinate _src1;

		private readonly Coordinate _src2;

		private readonly Coordinate _dest0;

		private readonly Coordinate _dest1;

		private readonly Coordinate _dest2;

		private double _m00;

		private double _m01;

		private double _m02;

		private double _m10;

		private double _m11;

		private double _m12;
	}
}
